package org.base.oj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.base.oj.common.BusinessException;
import org.base.oj.common.redis.RedisCache;
import org.base.oj.domain.LoginUser;
import org.base.oj.domain.User;
import org.base.oj.mapper.RolePermissionMapper;
import org.base.oj.mapper.UserMapper;
import org.base.oj.service.UserService;
import org.base.oj.utils.JwtUtil;
import org.base.oj.utils.MD5Utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    @Value("${GlobalValue.defultTokenMinute}")
    private Integer tokenMinute;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Value("${GlobalValue.redisLoginUserKey}")
    String redisLoginUserKey;
    @Override
    public void reg(User user) throws BusinessException {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, user.getUserName());
        User userForUserName = getOne(queryWrapper);
        if (userForUserName != null) {
            throw new BusinessException("用户名已存在");
        }
        user.setPassword(MD5Utils.MD5Upper(user.getPassword()));
        user.setStatus(0);
        save(user);
    }

    @Override
    public User getByUserName(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, userName);
        return getOne(queryWrapper);
    }

    @Override
    public Map<String, Object> login(User user) throws BusinessException {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) throw new BusinessException("用户名或密码错误");
        LoginUser principal = (LoginUser) authenticate.getPrincipal();
        String userId = principal.getUser().getId();
        principal.setPermission(rolePermissionMapper.getRolePermissionByUserPid(userId));
        //生成token
        String jwt = JwtUtil.createJWT(userId, userId, tokenMinute * 60L * 1000L);
        Map<String, Object> map = new HashMap<>();
        map.put("token", jwt);
        map.put("userName", principal.getUser().getUserName());
        map.put("userHead", principal.getUser().getUserHead());
        //存入redis
        redisCache.setCacheObject(redisLoginUserKey + userId , principal,tokenMinute , TimeUnit.MINUTES);
        return map;
    }
}
